// library/src/project_writer/mod.rs
use std::fs;
use std::io;
use std::io::Write;
use std::path::Path;
use walkdir::WalkDir;
use crate::config_loader::Config;

/// Writes the project structure with increased indentation to the output file.
pub fn write_project_structure(
    root: &Path,
    config: &Config,
    output_file: &mut fs::File,
) -> Result<(), io::Error> {
    // Write the project structure
    writeln!(
        output_file,
        "{} Project Structure:",
        config.comment_symbol
    )?;

    // Write specified directories
    for dir in &config.include_directories {
        let dir_path = root.join(dir);
        if dir_path.exists() {
            for entry in WalkDir::new(&dir_path) {
                let entry = entry?;
                let path = entry.path();
                let relative_path = path.strip_prefix(root).unwrap_or(path);
                let depth = relative_path.components().count();
                let indent = if depth > 0 {
                    "  ".repeat(depth - 1)
                } else {
                    String::new()
                };
                writeln!(
                    output_file,
                    "{}{}{}",
                    config.comment_symbol,
                    indent,
                    relative_path.display()
                )?;
            }
        }
    }

    // Write specified files
    for file in &config.include_files {
        let file_path = root.join(file);
        if file_path.exists() {
            // 修改这一行，借用 file_path
            let relative_path = file_path.strip_prefix(root).unwrap_or(&file_path);
            let depth = relative_path.components().count();
            let indent = if depth > 0 {
                "  ".repeat(depth - 1)
            } else {
                String::new()
            };
            writeln!(
                output_file,
                "{}{}{}",
                config.comment_symbol,
                indent,
                relative_path.display()
            )?;
        }
    }

    // Write the content of specified directories and files
    writeln!(
        output_file,
        "\n{} Project Files Content:",
        config.comment_symbol
    )?;
    for dir in &config.include_directories {
        let dir_path = root.join(dir);
        if dir_path.exists() {
            for entry in WalkDir::new(&dir_path) {
                let entry = entry?;
                if entry.file_type().is_file() {
                    write_file_content(&entry.path(), root, config, output_file)?;
                }
            }
        }
    }

    for file in &config.include_files {
        let file_path = root.join(file);
        if file_path.exists() {
            write_file_content(&file_path, root, config, output_file)?;
        }
    }

    Ok(())
}

/// Writes the content of a single file to the output file, preceded by its relative path as a comment.
fn write_file_content(
    file_path: &Path,
    root: &Path,
    config: &Config,
    output_file: &mut fs::File,
) -> Result<(), io::Error> {
    let relative_path = file_path.strip_prefix(root).unwrap_or(file_path);
    writeln!(
        output_file,
        "\n{}{} {}",
        config.comment_symbol,
        config.comment_symbol,
        relative_path.display()
    )?;
    let content = fs::read_to_string(file_path)?;
    writeln!(output_file, "{}", content)?;
    Ok(())
}